<script setup lang="ts">
  import { ref, reactive, computed, onMounted, watch } from 'vue'
  import { useRouter, useRoute } from 'vue-router'
  import { page as getBlogPage } from '@/api/blog'
  import { list as getTagList } from '@/api/tag'
  import { list as getCategoryList } from '@/api/category'
  import type { Blog, Category, Tag, BlogPageParam } from '@/types/api'
  import type { PageData } from '@/types/resp'
  import { ElMessage } from 'element-plus'

  const router = useRouter()
  const route = useRoute()

  // 页面状态
  const loading = ref(true)
  const posts = ref<Blog[]>([])
  const categories = ref<ExtendedCategory[]>([])
  const tags = ref<Tag[]>([])
  const pageData = ref<PageData<Blog>>({
    current: 1,
    pages: 0,
    size: 10,
    total: 0,
    records: [],
  })

  // 筛选条件
  const filters = reactive({
    keyword: '',
    selectedCategories: [] as string[], // 存储分类ID
    selectedTags: [] as string[], // 存储标签ID
    sortBy: 'date' as 'date' | 'views' | 'likes',
    order: 'desc' as 'asc' | 'desc',
  })

  // 分页
  const pagination = reactive({
    current: 1,
    pageSize: 10,
  })

  // 扩展的分类类型（添加显示所需的属性）
  interface ExtendedCategory extends Category {
    color?: string
    count?: number
    level?: number
    displayName?: string
  }

  // 计算属性：当前显示的文章
  const currentPosts = computed(() => {
    return pageData.value.records || []
  })

  // 计算分页数字
  const pageNumbers = computed(() => {
    const total = pageData.value.pages || 0
    const current = pageData.value.current || 1
    const delta = 2
    const range: number[] = []
    const rangeWithDots: (number | string)[] = []
    let l: number

    // 生成页码数组
    for (let i = 1; i <= total; i++) {
      if (i === 1 || i === total || (i >= current - delta && i <= current + delta)) {
        range.push(i)
      }
    }

    // 添加省略号
    range.forEach((i, _index) => {
      if (l) {
        if (i - l === 2) {
          rangeWithDots.push(l + 1)
        } else if (i - l !== 1) {
          rangeWithDots.push('...')
        }
      }
      rangeWithDots.push(i)
      l = i
    })

    return rangeWithDots
  })

  // 计算阅读时间
  const getReadTime = (content: string) => {
    const wordsPerMinute = 300
    const wordCount = content?.length || 0
    const minutes = Math.ceil(wordCount / wordsPerMinute)
    return `${minutes}分钟`
  }

  // 格式化日期
  const formatDate = (dateStr: string) => {
    if (!dateStr) return ''
    return new Date(dateStr).toLocaleDateString('zh-CN')
  }

  // 获取分类颜色 - 直接使用后端返回的颜色值
  const getCategoryColor = (category: Category): string => {
    return category?.color || '#409EFF'
  }

  // 方法：加载文章列表
  const loadPosts = async () => {
    try {
      loading.value = true

      // 构建排序参数
      let sort: number | undefined
      if (filters.sortBy === 'date') {
        sort = filters.order === 'desc' ? -1 : 1
      } else if (filters.sortBy === 'views') {
        sort = filters.order === 'desc' ? -2 : 2
      } else if (filters.sortBy === 'likes') {
        sort = filters.order === 'desc' ? -3 : 3
      }

      const params: BlogPageParam = {
        pageNum: pagination.current,
        pageSize: pagination.pageSize,
        keyword: filters.keyword || undefined,
        categories: filters.selectedCategories.length > 0 ? filters.selectedCategories : undefined,
        tags: filters.selectedTags.length > 0 ? filters.selectedTags : undefined,
        sort: sort,
      }

      const response = await getBlogPage(params)
      pageData.value = response
      posts.value = response.records
    } catch (error) {
      console.error('加载文章列表失败:', error)
      ElMessage.error('加载文章列表失败，请稍后重试')
    } finally {
      loading.value = false
    }
  }

  // 方法：加载分类列表
  const loadCategories = async () => {
    try {
      const response = await getCategoryList()

      // 转换为ExtendedCategory类型，后端现在返回平铺的分类列表
      const extendedCategories: ExtendedCategory[] = (response || [])
        .map(category => ({
          ...category,
          color: category.color || '#666', // 使用后端返回的颜色，如果没有则使用默认颜色
          count: category.count || 0, // 使用后端返回的文章数量统计（不包括子分类）
        }))
        .filter(category => category.count > 0) // 过滤掉数量为0的分类

      categories.value = extendedCategories
    } catch (error) {
      console.error('加载分类失败:', error)
      // 出错时使用空数组
      categories.value = []
    }
  }

  // 方法：加载标签列表
  const loadTags = async () => {
    try {
      const response = await getTagList()
      tags.value = response || []
    } catch (error) {
      console.error('加载标签失败:', error)
    }
  }

  // 方法：处理搜索
  const handleSearch = () => {
    pagination.current = 1
    loadPosts()
  }

  // 方法：处理标签筛选
  const handleTagFilter = (tagId: string) => {
    const index = filters.selectedTags.indexOf(tagId)
    if (index > -1) {
      filters.selectedTags.splice(index, 1)
    } else {
      filters.selectedTags.push(tagId)
    }
    pagination.current = 1
    loadPosts()
  }

  // 方法：处理排序
  const handleSort = (sortBy: typeof filters.sortBy) => {
    if (filters.sortBy === sortBy) {
      filters.order = filters.order === 'desc' ? 'asc' : 'desc'
    } else {
      filters.sortBy = sortBy
      filters.order = 'desc'
    }
    pagination.current = 1
    // 注：排序需要后端支持，目前仅保存状态
    loadPosts()
  }

  // 方法：处理分类筛选
  const handleCategoryFilter = (categoryId: string) => {
    const index = filters.selectedCategories.indexOf(categoryId)
    if (index > -1) {
      filters.selectedCategories.splice(index, 1)
    } else {
      filters.selectedCategories.push(categoryId)
    }
    pagination.current = 1
    loadPosts()
  }

  // 方法：处理分页
  const handlePageChange = (page: number | string) => {
    if (typeof page === 'number') {
      pagination.current = page
      loadPosts()
      // 滚动到顶部
      window.scrollTo({ top: 0, behavior: 'smooth' })
    }
  }

  // 方法：跳转到文章详情
  const handlePostClick = (postId: string) => {
    router.push(`/articles/${postId}`)
  }

  // 方法：清空筛选条件
  const clearFilters = () => {
    filters.keyword = ''
    filters.selectedCategories = []
    filters.selectedTags = []
    filters.sortBy = 'date'
    filters.order = 'desc'
    pagination.current = 1
    loadPosts()
  }

  // 监听分页变化
  watch(
    () => pageData.value.current,
    newVal => {
      pagination.current = newVal
    }
  )

  // 初始化
  onMounted(async () => {
    // 处理URL参数，直接使用标签ID
    if (route.query.tagId) {
      filters.selectedTags = [route.query.tagId as string]
    }

    // 并行加载所有数据
    await Promise.all([loadPosts(), loadCategories(), loadTags()])
  })
</script>

<template>
  <div class="article-list-page">
    <div class="container">
      <!-- 页面头部 -->
      <div class="page-header">
        <h1 class="page-title">📝 文章列表</h1>
        <p class="page-subtitle">探索技术世界，分享编程经验</p>
      </div>

      <!-- 筛选器 -->
      <div class="filters-section">
        <div class="filters-row">
          <!-- 搜索框 -->
          <div class="search-box">
            <input
              v-model="filters.keyword"
              type="text"
              placeholder="搜索文章标题或内容..."
              class="search-input"
              @keyup.enter="handleSearch"
            />
            <button class="search-btn" @click="handleSearch">🔍</button>
          </div>

          <!-- 排序选择 -->
          <div class="sort-options">
            <button
              v-for="option in [
                { key: 'date', label: '按时间' },
                { key: 'views', label: '按阅读' },
                { key: 'likes', label: '按点赞' },
              ]"
              :key="option.key"
              class="sort-btn"
              :class="{
                active: filters.sortBy === option.key,
                desc: filters.sortBy === option.key && filters.order === 'desc',
              }"
              @click="handleSort(option.key as typeof filters.sortBy)"
            >
              {{ option.label }}
              <span v-if="filters.sortBy === option.key" class="sort-arrow">
                {{ filters.order === 'desc' ? '↓' : '↑' }}
              </span>
            </button>
          </div>

          <!-- 清空筛选 -->
          <button class="clear-btn" @click="clearFilters">清空筛选</button>
        </div>

        <!-- 分类筛选 -->
        <div class="category-filters">
          <span class="filter-label">分类：</span>
          <button
            v-for="category in categories"
            :key="category.id"
            class="category-tag"
            :class="{ active: filters.selectedCategories.includes(category.id) }"
            :style="{ '--category-color': category.color }"
            @click="handleCategoryFilter(category.id)"
          >
            {{ category.name }}
            <span v-if="category.count && category.count > 0">({{ category.count }})</span>
          </button>
        </div>

        <!-- 标签筛选 -->
        <div class="tag-filters">
          <span class="filter-label">标签：</span>
          <button
            v-for="tag in tags"
            :key="tag.id"
            class="tag-item"
            :class="{ active: filters.selectedTags.includes(tag.id) }"
            :style="{ '--tag-color': tag.color || '#409EFF' }"
            @click="handleTagFilter(tag.id)"
          >
            {{ tag.name }} ({{ tag.count }})
          </button>
        </div>
      </div>

      <!-- 结果统计 -->
      <div class="results-info">
        <span>共找到 {{ pageData.total || 0 }} 篇文章</span>
        <span
          v-if="
            filters.keyword ||
            filters.selectedCategories.length > 0 ||
            filters.selectedTags.length > 0
          "
          class="filter-info"
        >
          （已筛选）
        </span>
      </div>

      <!-- 文章列表 -->
      <div class="articles-section">
        <div v-if="loading" class="loading-skeleton">
          <div v-for="i in 6" :key="i" class="skeleton-card">
            <div class="skeleton-content">
              <div class="skeleton-title"></div>
              <div class="skeleton-summary"></div>
              <div class="skeleton-meta"></div>
            </div>
          </div>
        </div>

        <div v-else-if="currentPosts.length === 0" class="empty-state">
          <div class="empty-icon">📝</div>
          <h3>暂无文章</h3>
          <p>
            {{
              filters.keyword ||
              filters.selectedCategories.length > 0 ||
              filters.selectedTags.length > 0
                ? '没有找到符合条件的文章'
                : '还没有发布任何文章'
            }}
          </p>
          <button
            v-if="
              filters.keyword ||
              filters.selectedCategories.length > 0 ||
              filters.selectedTags.length > 0
            "
            class="clear-btn"
            @click="clearFilters"
          >
            清空筛选条件
          </button>
        </div>

        <div v-else class="articles-grid">
          <article
            v-for="post in currentPosts"
            :key="post.id"
            class="article-card"
            @click="handlePostClick(post.id)"
          >
            <div class="card-content">
              <h3 class="card-title">{{ post.title }}</h3>
              <p class="card-summary">{{ post.summary || '暂无摘要' }}</p>

              <div class="card-meta">
                <span
                  v-if="post.category"
                  class="category"
                  :style="{ '--category-color': getCategoryColor(post.category) }"
                >
                  {{ post.category.name }}
                </span>
                <span class="publish-date">{{ formatDate(post.pushTime) }}</span>
                <span class="read-time">{{ getReadTime(post.mkContent) }}</span>
              </div>

              <div v-if="post.tags && post.tags.length > 0" class="card-tags">
                <span v-for="tag in post.tags" :key="tag.id" class="tag">{{ tag.name }}</span>
              </div>
            </div>

            <div class="card-stats">
              <div class="stat">
                <span class="stat-icon">👁</span>
                <span class="stat-value">{{ post.views || 0 }}</span>
              </div>
              <div class="stat">
                <span class="stat-icon">❤️</span>
                <span class="stat-value">{{ post.likes || 0 }}</span>
              </div>
            </div>
          </article>
        </div>

        <!-- 分页器 -->
        <div v-if="pageData.pages > 1" class="pagination">
          <button
            class="page-btn"
            :disabled="pagination.current === 1"
            @click="handlePageChange(pagination.current - 1)"
          >
            上一页
          </button>

          <div class="page-numbers">
            <button
              v-for="(page, index) in pageNumbers"
              :key="index"
              class="page-btn"
              :class="{ active: page === pagination.current }"
              :disabled="page === '...'"
              @click="handlePageChange(page)"
            >
              {{ page }}
            </button>
          </div>

          <button
            class="page-btn"
            :disabled="pagination.current === pageData.pages"
            @click="handlePageChange(pagination.current + 1)"
          >
            下一页
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
  .article-list-page {
    min-height: 100vh;
    padding: 2rem 0;
    background-color: var(--bg-color);
  }

  .page-header {
    text-align: center;
    margin-bottom: 3rem;

    .page-title {
      font-size: 2.5rem;
      font-weight: 700;
      color: var(--text-primary);
      margin: 0 0 1rem 0;
    }

    .page-subtitle {
      font-size: 1.1rem;
      color: var(--text-secondary);
      margin: 0;
    }
  }

  /* 筛选器样式 */
  .filters-section {
    background: var(--bg-color);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xl);
    padding: 2rem;
    margin-bottom: 2rem;
    box-shadow: var(--shadow-sm);
  }

  .filters-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
  }

  .search-box {
    flex: 1;
    min-width: 200px;
    display: flex;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    overflow: hidden;

    .search-input {
      flex: 1;
      padding: 0.75rem 1rem;
      border: none;
      background: transparent;
      color: var(--text-primary);
      font-size: 0.95rem;

      &::placeholder {
        color: var(--text-tertiary);
      }

      &:focus {
        outline: none;
      }
    }

    .search-btn {
      padding: 0.75rem 1rem;
      border: none;
      background: var(--primary-color);
      color: white;
      cursor: pointer;
      transition: background 0.2s ease;

      &:hover {
        background: var(--primary-hover);
      }
    }
  }

  .sort-options {
    display: flex;
    gap: 0.5rem;
  }

  .sort-btn {
    padding: 0.5rem 1rem;
    border: 1px solid var(--border-color);
    background: var(--bg-secondary);
    color: var(--text-secondary);
    border-radius: var(--radius-md);
    font-size: 0.9rem;
    cursor: pointer;
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    gap: 0.25rem;

    &:hover {
      border-color: var(--primary-color);
      color: var(--primary-color);
    }

    &.active {
      background: var(--primary-color);
      border-color: var(--primary-color);
      color: white;
    }
  }

  .clear-btn {
    padding: 0.5rem 1rem;
    border: 1px solid var(--border-secondary);
    background: transparent;
    color: var(--text-secondary);
    border-radius: var(--radius-md);
    font-size: 0.9rem;
    cursor: pointer;
    transition: all 0.2s ease;

    &:hover {
      border-color: var(--primary-color);
      color: var(--primary-color);
    }
  }

  .category-filters,
  .tag-filters {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1rem;
    flex-wrap: wrap;

    &:last-child {
      margin-bottom: 0;
    }

    .filter-label {
      margin-right: 0.5rem;
    }
  }

  .filter-label {
    font-weight: 500;
    color: var(--text-primary);
    white-space: nowrap;
  }

  .category-tag,
  .tag-item {
    padding: 0.4rem 0.8rem;
    border: 1px solid var(--border-color);
    background: var(--bg-secondary);
    color: var(--text-secondary);
    border-radius: var(--radius-lg);
    font-size: 0.85rem;
    cursor: pointer;
    transition: all 0.2s ease;
    // 添加统一的行高设置
    line-height: 1;
    display: inline-flex;
    align-items: center;

    &:hover {
      border-color: var(--tag-color, var(--primary-color));
      color: var(--tag-color, var(--primary-color));
    }

    &.active {
      background: var(--tag-color, var(--primary-color));
      border-color: var(--tag-color, var(--primary-color));
      color: white;
    }
  }

  .category-tag {
    &:hover {
      border-color: var(--category-color, var(--primary-color));
      color: var(--category-color, var(--primary-color));
    }

    &.active {
      background: var(--category-color, var(--primary-color));
      border-color: var(--category-color, var(--primary-color));
      color: white;
    }
  }

  /* 结果信息 */
  .results-info {
    margin-bottom: 1.5rem;
    color: var(--text-secondary);
    font-size: 0.9rem;
  }

  .filter-info {
    color: var(--primary-color);
    font-weight: 500;
  }

  /* 文章网格 */
  .articles-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
    gap: 1.5rem;
    margin-bottom: 3rem;
  }

  .article-card {
    background: var(--bg-color);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xl);
    padding: 1.5rem;
    cursor: pointer;
    transition: all 0.3s ease;
    display: flex;
    flex-direction: column;

    &:hover {
      border-color: var(--primary-color);
      box-shadow: var(--shadow-lg);
      transform: translateY(-4px);
    }
  }

  .card-content {
    flex: 1;
  }

  .card-title {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-primary);
    margin: 0 0 1rem 0;
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;

    &:hover {
      color: var(--primary-color);
    }
  }

  .card-summary {
    color: var(--text-secondary);
    line-height: 1.6;
    margin: 0 0 1.5rem 0;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .card-meta {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1rem;
    font-size: 0.85rem;
    color: var(--text-tertiary);
    flex-wrap: wrap;
  }

  .category {
    background: var(--category-color, var(--primary-color));
    color: white;
    padding: 0.25rem 0.6rem;
    border-radius: var(--radius-sm);
    font-size: 0.75rem;
    font-weight: 500;
    // 添加统一的行高设置
    line-height: 1;
    display: inline-flex;
    align-items: center;
  }

  .card-tags {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1rem;
    flex-wrap: wrap;
  }

  .tag {
    background: var(--bg-secondary);
    color: var(--text-secondary);
    padding: 0.2rem 0.5rem;
    border-radius: var(--radius-sm);
    font-size: 0.75rem;
    font-weight: 500;
    // 添加统一的行高设置
    line-height: 1;
    display: inline-flex;
    align-items: center;
  }

  .card-stats {
    display: flex;
    justify-content: flex-end;
    gap: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-color);
  }

  .stat {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.8rem;
    color: var(--text-tertiary);
  }

  /* 加载骨架屏 */
  .loading-skeleton {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
    gap: 1.5rem;
  }

  .skeleton-card {
    background: var(--bg-color);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xl);
    padding: 1.5rem;
  }

  .skeleton-title,
  .skeleton-summary,
  .skeleton-meta {
    height: 1rem;
    background: linear-gradient(
      90deg,
      var(--bg-secondary) 25%,
      var(--bg-tertiary) 50%,
      var(--bg-secondary) 75%
    );
    background-size: 200% 100%;
    animation: shimmer 1.5s infinite;
    border-radius: var(--radius-sm);
    margin-bottom: 1rem;
  }

  .skeleton-title {
    height: 1.5rem;
    width: 80%;
  }

  .skeleton-summary {
    width: 100%;
    height: 3rem;
  }

  .skeleton-meta {
    width: 60%;
    margin-bottom: 0;
  }

  @keyframes shimmer {
    0% {
      background-position: -200% 0;
    }

    100% {
      background-position: 200% 0;
    }
  }

  /* 空状态 */
  .empty-state {
    text-align: center;
    padding: 3rem;
    color: var(--text-secondary);

    .empty-icon {
      font-size: 4rem;
      margin-bottom: 1rem;
    }

    h3 {
      color: var(--text-primary);
      margin-bottom: 0.5rem;
    }

    p {
      margin-bottom: 2rem;
    }
  }

  /* 分页器 */
  .pagination {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 0.5rem;
  }

  .page-btn {
    padding: 0.5rem 1rem;
    border: 1px solid var(--border-color);
    background: var(--bg-color);
    color: var(--text-secondary);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all 0.2s ease;

    &:hover:not(:disabled) {
      border-color: var(--primary-color);
      color: var(--primary-color);
    }

    &.active {
      background: var(--primary-color);
      border-color: var(--primary-color);
      color: white;
    }

    &:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }
  }

  .page-numbers {
    display: flex;
    gap: 0.25rem;
  }

  /* 响应式设计 */
  @media (max-width: 768px) {
    .page-header .page-title {
      font-size: 2rem;
    }

    .filters-section {
      padding: 1.5rem;
    }

    .filters-row {
      flex-direction: column;
      align-items: stretch;
    }

    .search-box {
      min-width: auto;
    }

    .sort-options {
      justify-content: center;
    }

    .articles-grid {
      grid-template-columns: 1fr;
      gap: 1rem;
    }

    .article-card {
      padding: 1.25rem;
    }

    .card-meta {
      flex-direction: column;
      align-items: flex-start;
      gap: 0.5rem;
    }
  }

  @media (max-width: 480px) {
    .article-list-page {
      padding: 1rem 0;
    }

    .page-header .page-title {
      font-size: 1.75rem;
    }

    .filters-section {
      padding: 1rem;
    }

    .category-filters,
    .tag-filters {
      flex-direction: column;
      align-items: flex-start;
    }

    .article-card {
      padding: 1rem;
    }

    .pagination {
      flex-wrap: wrap;
    }
  }
</style>
